
#include "stdafx.h"
#include "rand.h"

using namespace tstd;

namespace Random
{
	void PerlinNoise::InitPermuteTable(PRNG& rand)
	{
		for(int i=0; i<256; ++i)
		{
			mPermuteTable[i] = mPermuteTable[i+256] = static_cast<int>(rand.randfn()*256);
		}
	}

	float PerlinNoise::Sample3D(float x, float y, float z)
	{
		int X = static_cast<int>(floor(x)) & 0xff;
		int Y = static_cast<int>(floor(y)) & 0xff;
		int Z = static_cast<int>(floor(z)) & 0xff;

		x -= floorf(x);
		y -= floorf(y);
		z -= floorf(z);

		float u = fade(x);
		float v = fade(y);
		float w = fade(z);

		int* p = mPermuteTable;

		int A = p[X]+Y;
		int AA = p[A]+Z;
		int AB = p[A+1]+Z;

		int B = p[X+1]+Y;
		int BA = p[B]+Z;
		int BB = p[B+1]+Z;

		return lerp(w, lerp(v,	lerp(u,	grad(p[AA],		x,		y,		z ),
										grad(p[BA],		x-1,	y,		z )), 
								lerp(u, grad(p[AB],		x,		y-1,	z ), 
										grad(p[BB],		x-1,	y-1,	z ))),
						lerp(v, lerp(u, grad(p[AA+1],	x,		y,		z-1),
										grad(p[BA+1],	x-1,	y,		z-1)),
								lerp(u, grad(p[AB+1],	x,		y-1,	z-1),
										grad(p[BB+1],	x-1,	y-1,	z-1))));
	}

}